package helper.base.string

import helper.base.A2LHM
import helper.base.LHMHelper.A2LHMExpand.toStr
import helper.base.LHMHelper.A3LHM
import helper.base.RegexHelper.StringTo.toKtVar
import helper.base.StringHelper.removeEmptyLine
import helper.base.string.ToStrHelper.TabStringUnit.Companion.makeTabStringUnit

// 定义 ToString 辅助工具集
object ToStrHelper {
    // 定义一个接口，为实现它的类提供格式化字符串表示的方法
    interface IToStr {
        // 根据提供的缩进等级生成对象的字符串表示
        fun toStr(tabNum: Int): String {
            val tsu = makeTabStringUnit(tabNum)
            return "${tsu.tabNumStr0}${this}"
        }

        // 生成无缩进的字符串表示并移除空行
        fun toStr0() = toStr(0).trim().removeEmptyLine()
    }

    // 扩展方法集合
    object Expand {
        // 针对 List<IToStr> 的扩展方法，生成其成员的字符串表示
        object ListE {
            object IToStrE {
                fun List<IToStr>.toStr(tabNum: Int = 0): String {
                    val tabNumStr = "\t".repeat(tabNum)
                    val sb = StringBuilder()
                    this.map {
                        sb.append("${tabNumStr}${it.toStr(tabNum)}\n")
                    }
                    return sb.toString()
                }
            }

            // 针对 List<E> 的扩展方法，生成列表的字符串表示
            object EE {
                fun <E> List<E>.toStr(
                    tabNum: Int = 0,
                    listName: String = "",
                ): String {
                    val sb = StringBuilder()
                    val tsu = makeTabStringUnit(tabNum)
                    sb.append("${tsu.tabNumStr0}${listName}=[\n")
                    this.map {
                        sb.append("${tsu.tabNumStr1}${it}\n")
                    }
                    sb.append("${tsu.tabNumStr0}],size=${size}\n")
                    return sb.toString().removeEmptyLine()
                }
            }
        }
    }

    // 定义一个表示缩进单位的类
    class TabStringUnit(
        val tabNum0: Int = 0,
        private val tabStr: String = "\t",
    ) {
        companion object {
            fun makeTabStringUnit(
                tabNum: Int = 0,
                tabStr: String = "\t",
            ): TabStringUnit {
                return TabStringUnit(
                    tabNum,
                    tabStr,
                )
            }
        }

        fun getTabNum(i: Int = 0): Int {
            return tabNum0 + i
        }

        private fun getTabNumStrByTabNum(theTabNum: Int = 0): String {
            return tabStr.repeat(theTabNum)
        }

        fun getTabNumStr(i: Int = 0): String {
            return getTabNumStrByTabNum(getTabNum(i))
        }

        val tabNum1: Int
            get() = getTabNum(1)
        val tabNum2: Int
            get() = getTabNum(2)
        val tabNum3: Int
            get() = getTabNum(3)

        val tabNumStr0: String
            get() = getTabNumStrByTabNum(tabNum0)
        val tabNumStr1: String
            get() = getTabNumStrByTabNum(tabNum1)
        val tabNumStr2: String
            get() = getTabNumStrByTabNum(tabNum2)
        val tabNumStr3: String
            get() = getTabNumStrByTabNum(tabNum3)
    }

    // 定义扩展方法，为不同类型的对象生成格式化字符串并添加到 StringBuilder
    fun Any?.toSBStr(
        sb: StringBuilder,
        tsu: TabStringUnit,
        i: Int,
    ) {
        if (this is IToStr) {
            sb.append("${this.toStr(tsu.getTabNum(i))}\n")
            return
        }
        if (this is ArrayList<*>) {
            sb.append("${tsu.getTabNumStr(i)}[\n")
            this.forEach {
                it.toSBStr(sb, tsu, i + 1)
            }
            sb.append("${tsu.getTabNumStr(i)}],size=${size}\n")
            return
        }
        if (this is List<*>) {
            sb.append("${tsu.getTabNumStr(i)}[\n")
            this.forEach {
                it.toSBStr(sb, tsu, i + 1)
            }
            sb.append("${tsu.getTabNumStr(i)}],size=${size}\n")
            return
        }
        if (this is A3LHM<*, *, *>) {
            sb.append("${this.toStr(tsu.getTabNum(i))}\n")
            return
        }
        if (this is A2LHM<*, *>) {
            sb.append("${this.toStr(tsu.getTabNum(i))}\n")
            return
        }
        sb.append("${tsu.getTabNumStr(i)}${this}\n")
    }

    // 定义扩展方法，为对象添加名称并生成格式化字符串
    fun Any?.toSBStr(
        sb: StringBuilder,
        tsu: TabStringUnit,
        name: String,
        i: Int,
    ): String {
        sb.append("${tsu.getTabNumStr(i)}${name}=\n")
        this.toSBStr(sb, tsu, i + 1)
        return sb.toString()
    }

    // 定义方法，为对象生成格式化字符串，包含名称
    fun Any?.toSBStr(name: String = ""): String {
        return this.toSBStr(
            StringBuilder(),
            makeTabStringUnit(),
            name,
            0,
        )
    }

    // 定义示例类，实现 IToStr 接口，展示如何生成类的格式化字符串表示
    private class InstanceClass(
        val a1: String,
        val a2: String,
    ) : IToStr {
        override fun toStr(
            tabNum: Int,
        ): String {
            val sb = StringBuilder()
            val tsu = makeTabStringUnit(tabNum)
            sb.append("${tsu.tabNumStr0}InstanceClass(\n")
            a1.toSBStr(sb, tsu, "a1", 1)
            a2.toSBStr(sb, tsu, "a2", 1)
            sb.append("${tsu.tabNumStr0})\n")
            return sb.toString().removeEmptyLine()
        }
    }

    object Tasks {
        object T1 {
            @JvmStatic
            fun main(args: Array<String>) {
                """
        val dss: DoubleArrayListArrayList
                """.trimIndent().split("\n").forEach {
                    val toKtVar = it.toKtVar()
                    println("${toKtVar}.toSBStr(sb, tsu, \"${toKtVar}\", 1)")
                }
            }
        }
    }
}